﻿using App.Common;
using App.Common.Db;
using App.IService;
using App.Model;
using App.Model.DTO.Article;
using App.Model.DTO.User;
using App.Service;
using App.WebAPI.Utilty._Filter;
using App.WebAPI.Utilty.ApiResult;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;

namespace App.WebAPI.Controllers
{
    /// <summary>
    /// 文章接口
    /// </summary>
    [Route("[controller]/[Action]")]
    [ApiController]
    public class ArticleController : ControllerBase
    {
        private readonly ILogger<ArticleController> _logger;
        private readonly IArticleService _iArticleService;
        public ArticleController(IArticleService iArticleService, ILogger<ArticleController> logger)
        {
            _logger = logger;
            _iArticleService = iArticleService;
        }
        /// <summary>
        /// 获取文章列表
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous] // 添加此特性允许匿名访问
        [HttpGet]
        public async Task<ActionResult<ApiResult>> GetList([FromServices] IMapper iMapper)
        {

            var data = await _iArticleService.QueryAsync();
            if (data.Count == 0) return ApiResultHelper.Error("没有更多文章");
            try
            {
                var articleDTO = iMapper.Map<List<ArticleDTO>>(data);
                return ApiResultHelper.Success(articleDTO, data.Count, true);
            }
            catch (Exception)
            {
                return ApiResultHelper.Error("服务器异常");
            }
        }

        /// <summary>
        /// 文章详情
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous] // 添加此特性允许匿名访问
        [HttpGet]
        public async Task<ApiResult> GetArticleDetail(string id, [FromServices] IMapper iMapper)
        {
            var data = await _iArticleService.FindAsync(id);
            if (data == null) return ApiResultHelper.Error("没有找到该文章");
            data.BrowseCount++;
            await _iArticleService.EditAsync(data);
            var articleDto = iMapper.Map<ArticleDTO>(data);
            return ApiResultHelper.Success(articleDto, true);
        }
        /// <summary>
        /// 文章点赞
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        //[TypeFilter(typeof(CustomResourceFilterAttribute))]
        [Authorize]
        [HttpPost]
        public async Task<ApiResult> CheckLike(CheckLikeRequestInput req, [FromServices] IMapper iMapper)
        {
            var article = await _iArticleService.FindAsync(req.Id);
            if (article == null) return ApiResultHelper.Error("没有找到该文章");

            var userId = User.FindFirst(ClaimTypes.Name).Value;

            // 检查用户是否已经点赞过该文章
            if (article.UserLikes == null)
            {
                article.UserLikes = new List<string>();

            }
            if (article.UserLikes.Contains(userId)) return ApiResultHelper.Error("您已经点赞过该文章");

            // 添加用户点赞记录
            article.UserLikes.Add(userId);

            // 更新文章的点赞数
            article.LikeCount++;
            await _iArticleService.EditAsync(article);
            var updatedArticle = await _iArticleService.FindAsync(req.Id); // 重新查询
            var articleDto = iMapper.Map<ArticleDTO>(updatedArticle); // 转换为DTO

            return ApiResultHelper.Success(articleDto, true);
        }
        /// <summary>
        /// 取消文章点赞
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ApiResult> UnlikeArticle(UnlikeArticleRequestInput req, [FromServices] IMapper iMapper)
        {
            var article = await _iArticleService.FindAsync(req.Id);
            if (article == null) return ApiResultHelper.Error("没有找到该文章");

            var userId = User.FindFirst(ClaimTypes.Name).Value;

            // 检查用户是否已经点赞过该文章
            if (article.UserLikes == null || !article.UserLikes.Contains(userId)) return ApiResultHelper.Error("您还没有点赞该文章");

            // 移除用户点赞记录
            article.UserLikes.Remove(userId);

            // 更新文章的点赞数
            article.LikeCount--;
            await _iArticleService.EditAsync(article);
            var updatedArticle = await _iArticleService.FindAsync(req.Id); // 重新查询
            var articleDto = iMapper.Map<ArticleDTO>(updatedArticle); // 转换为DTO
            return ApiResultHelper.Success(articleDto, true);
        }
        /// <summary>
        /// 获取自己创建的文章列表
        /// </summary>
        /// <param name="iMapper"></param>
        /// <param name="req"></param>
        /// <returns></returns>
        //[HttpGet]
        //public async Task<ActionResult<ApiResult>> GetOwnArticle()
        //{
        //    string id = User.FindFirst(ClaimTypes.Name).Value;
        //    var data = await _iArticleService.QueryAsync(c => c.UserId == id);
        //    if (data.Count == 0) return ApiResultHelper.Error("没有更多文章");
        //    return ApiResultHelper.Success(data);
        //}
        /// <summary>
        /// 获取文章分页列表
        /// </summary>
        /// <param name="iMapper"></param>
        /// <param name="req"></param>
        /// <returns></returns>
        [AllowAnonymous] // 添加此特性允许匿名访问
        [HttpPost]
        public async Task<ApiResult> GetPageList([FromServices] IMapper iMapper, [FromBody] QueryArtilceRequestInput req)
        {
            RefAsync<int> total = 0;
            Expression<Func<Article, bool>> func = u => true;
            List<Article> article = null;
            if (!string.IsNullOrEmpty(req.Filter))
            {
                func = u => u.Title.Contains(req.Filter) || u.Content.Contains(req.Filter);
            }
            if (!string.IsNullOrEmpty(req.Status))
            {
                if (req.Status == "DRAFT")
                {
                    func = u => u.Status == ArticleStatusEnum.DRAFT;
                }
                else if (req.Status == "PUBLISH")
                {
                    func = u => u.Status == ArticleStatusEnum.PUBLISH;
                }

            }
            if (!string.IsNullOrEmpty(req.Filter) && !string.IsNullOrEmpty(req.Status))
            {
                func = u => ((u.Title.Contains(req.Filter)||u.Content.Contains(req.Filter)) && (req.Status == "PUBLISH" ? u.Status == ArticleStatusEnum.PUBLISH : u.Status == ArticleStatusEnum.DRAFT));
            }
            if (!string.IsNullOrEmpty(req.ClassificationId))
            {
                func = u => u.ClassificationId.Contains(req.ClassificationId);
            }
            if (!string.IsNullOrEmpty(req.ClassificationId) && !string.IsNullOrEmpty(req.Status))
            {
                func = u => (u.ClassificationId.Contains(req.ClassificationId) && (req.Status == "PUBLISH" ? u.Status == ArticleStatusEnum.PUBLISH : u.Status == ArticleStatusEnum.DRAFT));
            }
            if (req.PageIndex == 1 && req.PageSize == int.MaxValue)
            {
                var allArticle = func != null ? await _iArticleService.QueryAsync(func) : await _iArticleService.QueryAsync();
                total = allArticle.Count;
                article = allArticle;
            }
            else
            {
                article = await _iArticleService.QueryAsync(func ?? (u => true), req.PageIndex, req.PageSize, total);
            }
            try
            {
                var articleDTO = iMapper.Map<List<ArticleDTO>>(article);
                return ApiResultHelper.Success(articleDTO, total, true);
            }
            catch (Exception)
            {
                return ApiResultHelper.Error("服务器异常");
            }
        }
        /// <summary>
        /// 创建文章
        /// </summary>
        /// <param name="title"></param>
        /// <param name="content"></param>
        /// <param name="classificationId"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> Create(CreateArticleRequestInput req)
        {
            var id = GuidCombGenerator.GenerateCombGuid32();
            //数据验证
            Article article = new Article
            {
                BrowseCount = 0,
                Content = req.Content,
                LikeCount = 0,
                CreateAt = DateTime.Now,
                UpdateAt = DateTime.Now,
                Title = req.Title,
                CoverImages = req.CoverImages,
                ClassificationId = req.ClassificationId,
                UserId = User.FindFirst(ClaimTypes.Name).Value,
                Status = ArticleStatusEnum.DRAFT,
                IsOriginal = req.IsOriginal,
                Id = id,
                Tags = req.Tags.ToList()
            };
            bool b = await _iArticleService.CreateAsync(article);
            if (!b) return ApiResultHelper.Error("添加失败,服务器发生错误");
            return ApiResultHelper.Success(article, b);
        }
        /// <summary>
        /// 删除文章
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> Delete(DeleteArticleRequestInput req)
        {
            bool b = await _iArticleService.DeleteAsync(req.Id);
            if (!b) return ApiResultHelper.Error("删除失败,服务器发生错误");
            return ApiResultHelper.Success(b);
        }
        /// <summary>
        /// 编辑文章
        /// </summary>
        /// <param name="id"></param>
        /// <param name="title"></param>
        /// <param name="content"></param>
        /// <param name="classificationId"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> Edit(EditArticleRequestInput req)
        {
            var updateArticle = await _iArticleService.FindAsync(req.Id);
            if (updateArticle == null) return ApiResultHelper.Error("没有找到该文章");
            updateArticle.Title = req.Title;
            updateArticle.Content = req.Content;
            updateArticle.ClassificationId = req.ClassificationId;
            updateArticle.CoverImages = req.CoverImages;
            updateArticle.Status = ArticleStatusEnum.DRAFT;
            updateArticle.Tags = req.Tags.ToList();
            updateArticle.IsOriginal = req.IsOriginal;
            updateArticle.UpdateAt = DateTime.Now;
            bool b = await _iArticleService.EditAsync(updateArticle);
            if (!b) return ApiResultHelper.Error("修改失败,服务器发生错误");
            return ApiResultHelper.Success(updateArticle, b);
        }
        /// <summary>
        /// 发布文章
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> Publish(PublishArticleRequestInput req)
        {
            var updateArticle = await _iArticleService.FindAsync(req.Id);
            if (updateArticle == null) return ApiResultHelper.Error("没有找到该文章");
            updateArticle.Status = ArticleStatusEnum.PUBLISH;
            bool b = await _iArticleService.EditAsync(updateArticle);
            if (!b) return ApiResultHelper.Error("发布失败,服务器发生错误");
            return ApiResultHelper.Success(updateArticle, b);
        }
        /// <summary>
        /// 取消发布文章
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> CancelPublish(CancelPublishArticleRequestInput req)
        {
            var updateArticle = await _iArticleService.FindAsync(req.Id);
            if (updateArticle == null) return ApiResultHelper.Error("没有找到该文章");
            updateArticle.Status = ArticleStatusEnum.DRAFT;
            bool b = await _iArticleService.EditAsync(updateArticle);
            if (!b) return ApiResultHelper.Error("取消发布失败,服务器发生错误");
            return ApiResultHelper.Success(updateArticle, b);
        }
        /// <summary>
        /// 批量发布
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> BatchPublish([FromBody] List<string> ids)
        {
            List<string> alreadyPublishedTitles = new List<string>();

            foreach (var id in ids)
            {
                var article = await _iArticleService.FindAsync(id);
                if (article != null && article.Status == ArticleStatusEnum.PUBLISH)
                {
                    alreadyPublishedTitles.Add(article.Title);
                }
            }

            if (alreadyPublishedTitles.Any())
            {
                string errorMessage = $"以下文章已发布，不允许重复发布：{string.Join(",", alreadyPublishedTitles.Select(title => $"《{title}》"))}";
                return ApiResultHelper.Error(errorMessage);
            }

            bool b = await _iArticleService.BatchPublishAsync(ids);
            if (!b) return ApiResultHelper.Error("批量发布失败,服务器发生错误");
            return ApiResultHelper.Success("批量发布成功", b);
        }
        /// <summary>
        /// 批量取消发布
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> BatchUnpublish([FromBody] List<string> ids)
        {

            List<string> alreadyUnPublishedTitles = new List<string>();

            foreach (var id in ids)
            {
                var article = await _iArticleService.FindAsync(id);
                if (article != null && article.Status == ArticleStatusEnum.DRAFT)
                {
                    alreadyUnPublishedTitles.Add(article.Title);
                }
            }

            if (alreadyUnPublishedTitles.Any())
            {
                string errorMessage = $"以下文章已是草稿状态，不允许重复取消发布：{string.Join(",", alreadyUnPublishedTitles.Select(title => $"《{title}》"))}";
                return ApiResultHelper.Error(errorMessage);
            }

            bool b = await _iArticleService.BatchUnpublishAsync(ids);
            if (!b) return ApiResultHelper.Error("批量取消发布失败,服务器发生错误");
            return ApiResultHelper.Success("批量取消发布成功", b);
        }
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> BatchDelete([FromBody] List<string> ids)
        {
            bool b = await _iArticleService.BatchDeleteAsync(ids);
            if (!b) return ApiResultHelper.Error("批量删除失败,服务器发生错误");
            return ApiResultHelper.Success("批量删除成功", b);
        }
        /// <summary>
        /// 批量软删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> BatchSoftDelete([FromBody] List<string> ids)
        {
            List<string> publishedTitles = new List<string>();
            List<string> deletableIds = new List<string>();

            foreach (var id in ids)
            {
                var article = await _iArticleService.FindAsync(id);
                if (article != null)
                {
                    if (article.Status == ArticleStatusEnum.PUBLISH)
                    {
                        publishedTitles.Add(article.Title);
                    }
                    else
                    {
                        deletableIds.Add(id);
                    }
                }
            }
            if (publishedTitles.Any())
            {
                string warningMessage = $"以下文章处于发布状态，无法删除：{string.Join("、", publishedTitles.Select(title => $"《{title}》"))}";

                if (!deletableIds.Any())
                {
                    return ApiResultHelper.Error(warningMessage);
                }

                bool deleteResult = await _iArticleService.BatchSoftDeleteAsync(deletableIds);
                if (!deleteResult)
                {
                    return ApiResultHelper.Error("批量删除失败，服务器发生错误");
                }

                return ApiResultHelper.Success($"部分文章删除成功。{warningMessage}", deleteResult);
            }

            if (!deletableIds.Any())
            {
                return ApiResultHelper.Error("没有可删除的文章");
            }

            bool b = await _iArticleService.BatchSoftDeleteAsync(deletableIds);
            if (!b) return ApiResultHelper.Error("批量删除失败，服务器发生错误");
            return ApiResultHelper.Success("批量删除成功", b);
        }
        /// <summary>
        /// 批量恢复删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> BatchRestore([FromBody] List<string> ids)
        {
            bool b = await _iArticleService.BatchRestoreAsync(ids);
            if (!b) return ApiResultHelper.Error("批量恢复失败,服务器发生错误");
            return ApiResultHelper.Success("批量恢复成功", b);
        }
        /// <summary>
        /// 获取文章回收站列表
        /// </summary>
        /// <param name="iMapper"></param>
        /// <returns></returns>
        [Authorize]
        [HttpGet]
        public async Task<ActionResult<ApiResult>> GetSoftDeletedList([FromServices] IMapper iMapper)
        {
            var data = await _iArticleService.QuerySoftDeletedAsync(a => true);
            if (data.Count == 0) return ApiResultHelper.Error("没有已删除的文章");
            try
            {
                var articleDTO = iMapper.Map<List<ArticleDTO>>(data);
                return ApiResultHelper.Success(articleDTO, data.Count, true);
            }
            catch (Exception)
            {
                return ApiResultHelper.Error("服务器异常");
            }
        }
        /// <summary>
        /// 获取回收站分页列表
        /// </summary>
        /// <param name="iMapper"></param>
        /// <param name="req"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ApiResult> GetSoftDeletedPageList([FromServices] IMapper iMapper, [FromBody] QuerySoftDeleteArtilceRequestInput req)
        {
            RefAsync<int> total = 0;
            Expression<Func<Article, bool>> func = u => true;
            List<Article> article = null;
            if (!string.IsNullOrEmpty(req.Filter))
            {
                func = u => u.Title.Contains(req.Filter) || u.Content.Contains(req.Filter);
            }
            if (req.PageIndex == 1 && req.PageSize == int.MaxValue)
            {
                var allArticle = func != null ? await _iArticleService.QueryAsync(func) : await _iArticleService.QueryAsync();
                total = allArticle.Count;
                article = allArticle;
            }
            else
            {
                article = await _iArticleService.QuerySoftDeletedAsync(func ?? (u => true), req.PageIndex, req.PageSize, total);
            }
            try
            {
                var articleDTO = iMapper.Map<List<ArticleDTO>>(article);
                return ApiResultHelper.Success(articleDTO, total, true);
            }
            catch (Exception)
            {
                return ApiResultHelper.Error("服务器异常");
            }
        }

        /// <summary>
        /// 设置置顶
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isTop"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> SetTop([FromBody] ArticleSetTopRequestInput req)
        {
            bool b = await _iArticleService.SetTopAsync(req.Id, req.IsTop);
            if (!b) return ApiResultHelper.Error(req.IsTop ? "文章置顶失败" : "取消置顶失败");
            return ApiResultHelper.Success(req.IsTop ? "文章置顶成功" : "取消置顶成功",b);
        }
        /// <summary>
        /// 软删除文章
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> SoftDelete(DeleteArticleRequestInput req)
        {
            bool b = await _iArticleService.SoftDeleteAsync(req.Id);
            if (!b) return ApiResultHelper.Error("删除失败，服务器异常");
            return ApiResultHelper.Success("删除成功", b);

        }
        /// <summary>
        /// 单个文章恢复
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult<ApiResult>> Restore(RestoreRequestInput req)
        {
            bool b = await _iArticleService.RestoreAsync(req.Id);
            if (!b) return ApiResultHelper.Error("恢复失败，服务器异常");
            return ApiResultHelper.Success("恢复成功", b);

        }

    }
}
